home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / Level 1 Extensions 29Sep94 / IconButton.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  9.5 KB  |  325 lines  |  [TEXT/KAHL]

  1. /* IconButton.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    System Dependency Library for Building Portable Software               */
  5. /*    Macintosh Version                                                      */
  6. /*    Written by Thomas R. Lawrence, 1993 - 1994.                            */
  7. /*                                                                           */
  8. /*    This file is Public Domain; it may be used for any purpose whatsoever  */
  9. /*    without restriction.                                                   */
  10. /*                                                                           */
  11. /*    This package is distributed in the hope that it will be useful,        */
  12. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  13. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   */
  14. /*                                                                           */
  15. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  16. /*                                                                           */
  17. /*****************************************************************************/
  18.  
  19. #include "MiscInfo.h"
  20. #include "Audit.h"
  21. #include "Debug.h"
  22. #include "Definitions.h"
  23.  
  24. #include "IconButton.h"
  25. #include "Memory.h"
  26. #include "EventLoop.h"
  27.  
  28.  
  29. struct IconButtonRec
  30.     {
  31.         WinType*                    Window;
  32.         OrdType                        XLoc;
  33.         OrdType                        YLoc;
  34.         OrdType                        Width;
  35.         OrdType                        Height;
  36.         Bitmap*                        Unselected;
  37.         Bitmap*                        UnselectedMouseDown;
  38.         Bitmap*                        Selected;
  39.         Bitmap*                        SelectedMouseDown;
  40.         MyBoolean                    DisposeBitmapsWhenDone;
  41.         MyBoolean                    ButtonState;
  42.         IconButtonModes        Mode;
  43.     };
  44.  
  45.  
  46. /* allocate a new icon button.  This one is used if the button should convert */
  47. /* the specified raw images into internal bitmaps. */
  48. IconButtonRec*    NewIconButtonRawBitmaps(WinType* Window, OrdType X, OrdType Y,
  49.                                     OrdType Width, OrdType Height, unsigned char* RawUnselected,
  50.                                     unsigned char* RawUnselectedMouseDown, unsigned char* RawSelected,
  51.                                     unsigned char* RawSelectedMouseDown, int BytesPerRow,
  52.                                     IconButtonModes WhatMode)
  53.     {
  54.         IconButtonRec*    TheButton;
  55.  
  56.         TheButton = (IconButtonRec*)AllocPtrCanFail(sizeof(IconButtonRec),"IconButtonRec");
  57.         if (TheButton == NIL)
  58.             {
  59.              FailurePoint1:
  60.                 return NIL;
  61.             }
  62.         TheButton->Unselected = MakeBitmap(RawUnselected,Width,Height,BytesPerRow);
  63.         if (TheButton->Unselected == NIL)
  64.             {
  65.              FailurePoint2:
  66.                 ReleasePtr((char*)TheButton);
  67.                 goto FailurePoint1;
  68.             }
  69.         TheButton->UnselectedMouseDown = MakeBitmap(RawUnselectedMouseDown,
  70.             Width,Height,BytesPerRow);
  71.         if (TheButton->UnselectedMouseDown == NIL)
  72.             {
  73.              FailurePoint3:
  74.                 DisposeBitmap(TheButton->Unselected);
  75.                 goto FailurePoint2;
  76.             }
  77.         TheButton->Selected = MakeBitmap(RawSelected,Width,Height,BytesPerRow);
  78.         if (TheButton->Selected == NIL)
  79.             {
  80.              FailurePoint4:
  81.                 DisposeBitmap(TheButton->UnselectedMouseDown);
  82.                 goto FailurePoint3;
  83.             }
  84.         TheButton->SelectedMouseDown = MakeBitmap(RawSelectedMouseDown,
  85.             Width,Height,BytesPerRow);
  86.         if (TheButton->SelectedMouseDown == NIL)
  87.             {
  88.              FailurePoint5:
  89.                 DisposeBitmap(TheButton->Selected);
  90.                 goto FailurePoint4;
  91.             }
  92.         TheButton->DisposeBitmapsWhenDone = True;
  93.         TheButton->Window = Window;
  94.         TheButton->XLoc = X;
  95.         TheButton->YLoc = Y;
  96.         TheButton->Width = Width;
  97.         TheButton->Height = Height;
  98.         TheButton->ButtonState = False;
  99.         TheButton->Mode = WhatMode;
  100.         return TheButton;
  101.     }
  102.  
  103.  
  104. /* allocate a new icon button.  this one is used if the bitmaps are already */
  105. /* allocated and you just want to use them.  when disposed, the bitmaps will NOT */
  106. /* be disposed. */
  107. IconButtonRec*    NewIconButtonPreparedBitmaps(WinType* Window, OrdType X, OrdType Y,
  108.                                     OrdType Width, OrdType Height, Bitmap* Unselected,
  109.                                     Bitmap* UnselectedMouseDown, Bitmap* Selected,
  110.                                     Bitmap* SelectedMouseDown, IconButtonModes WhatMode)
  111.     {
  112.         IconButtonRec*    TheButton;
  113.  
  114.         TheButton = (IconButtonRec*)AllocPtrCanFail(sizeof(IconButtonRec),"IconButtonRec");
  115.         if (TheButton == NIL)
  116.             {
  117.              FailurePoint1:
  118.                 return NIL;
  119.             }
  120.         TheButton->Window = Window;
  121.         TheButton->XLoc = X;
  122.         TheButton->YLoc = Y;
  123.         TheButton->Width = Width;
  124.         TheButton->Height = Height;
  125.         TheButton->Unselected = Unselected;
  126.         TheButton->UnselectedMouseDown = UnselectedMouseDown;
  127.         TheButton->Selected = Selected;
  128.         TheButton->SelectedMouseDown = SelectedMouseDown;
  129.         TheButton->DisposeBitmapsWhenDone = False;
  130.         TheButton->ButtonState = False;
  131.         TheButton->Mode = WhatMode;
  132.         return TheButton;
  133.     }
  134.  
  135.  
  136. /* dispose the button, and the bitmaps if appropriate */
  137. void                        DisposeIconButton(IconButtonRec* TheButton)
  138.     {
  139.         CheckPtrExistence(TheButton);
  140.         if (TheButton->DisposeBitmapsWhenDone)
  141.             {
  142.                 DisposeBitmap(TheButton->Unselected);
  143.                 DisposeBitmap(TheButton->UnselectedMouseDown);
  144.                 DisposeBitmap(TheButton->Selected);
  145.                 DisposeBitmap(TheButton->SelectedMouseDown);
  146.             }
  147.         ReleasePtr((char*)TheButton);
  148.     }
  149.  
  150.  
  151. /* find out where the icon button is */
  152. OrdType                    GetIconButtonXLoc(IconButtonRec* TheButton)
  153.     {
  154.         CheckPtrExistence(TheButton);
  155.         return TheButton->XLoc;
  156.     }
  157.  
  158.  
  159. /* find out where the icon button is */
  160. OrdType                    GetIconButtonYLoc(IconButtonRec* TheButton)
  161.     {
  162.         CheckPtrExistence(TheButton);
  163.         return TheButton->YLoc;
  164.     }
  165.  
  166.  
  167. /* find out where the icon button is */
  168. OrdType                    GetIconButtonWidth(IconButtonRec* TheButton)
  169.     {
  170.         CheckPtrExistence(TheButton);
  171.         return TheButton->Width;
  172.     }
  173.  
  174.  
  175. /* find out where the icon button is */
  176. OrdType                    GetIconButtonHeight(IconButtonRec* TheButton)
  177.     {
  178.         CheckPtrExistence(TheButton);
  179.         return TheButton->Height;
  180.     }
  181.  
  182.  
  183. /* change the location of the icon button */
  184. void                        SetIconButtonLocation(IconButtonRec* TheButton, OrdType X, OrdType Y)
  185.     {
  186.         CheckPtrExistence(TheButton);
  187.         TheButton->XLoc = X;
  188.         TheButton->YLoc = Y;
  189.         RedrawIconButton(TheButton);
  190.     }
  191.  
  192.  
  193. /* this is an internal routine for redrawing the button. */
  194. static void            IconButtonInternalRedraw(IconButtonRec* TheButton, MyBoolean MouseDown)
  195.     {
  196.         CheckPtrExistence(TheButton);
  197.         SetClipRect(TheButton->Window,TheButton->XLoc,TheButton->YLoc,
  198.             TheButton->Width,TheButton->Height);
  199.         if (TheButton->ButtonState)
  200.             {
  201.                 if (MouseDown)
  202.                     {
  203.                         CheckPtrExistence(TheButton->SelectedMouseDown);
  204.                         DrawBitmap(TheButton->Window,TheButton->XLoc,TheButton->YLoc,
  205.                             TheButton->SelectedMouseDown);
  206.                     }
  207.                  else
  208.                     {
  209.                         CheckPtrExistence(TheButton->Selected);
  210.                         DrawBitmap(TheButton->Window,TheButton->XLoc,TheButton->YLoc,
  211.                             TheButton->Selected);
  212.                     }
  213.             }
  214.          else
  215.             {
  216.                 if (MouseDown)
  217.                     {
  218.                         CheckPtrExistence(TheButton->UnselectedMouseDown);
  219.                         DrawBitmap(TheButton->Window,TheButton->XLoc,TheButton->YLoc,
  220.                             TheButton->UnselectedMouseDown);
  221.                     }
  222.                  else
  223.                     {
  224.                         CheckPtrExistence(TheButton->Unselected);
  225.                         DrawBitmap(TheButton->Window,TheButton->XLoc,TheButton->YLoc,
  226.                             TheButton->Unselected);
  227.                     }
  228.             }
  229.     }
  230.  
  231.  
  232. /* do a full redraw of the button */
  233. void                        RedrawIconButton(IconButtonRec* TheButton)
  234.     {
  235.         CheckPtrExistence(TheButton);
  236.         IconButtonInternalRedraw(TheButton,False);
  237.     }
  238.  
  239.  
  240. /* handle a mouse down in the button.  returns True if the state of the button */
  241. /* changed.  (or if the mouse went up inside the button, if it is in simple */
  242. /* button mode.)  If Tracking != NIL, then it will be repeatedly called, with */
  243. /* the Inside status until the mouse goes up. */
  244. MyBoolean                IconButtonMouseDown(IconButtonRec* TheButton, OrdType X, OrdType Y,
  245.                                     void (*Tracking)(void* Refcon, MyBoolean Inside), void* Refcon)
  246.     {
  247.         MyBoolean                Inside;
  248.         MyBoolean                OldInside;
  249.  
  250.         OldInside = False;
  251.         do
  252.             {
  253.                 Inside = IconButtonHitTest(TheButton,X,Y);
  254.                 if (Inside != OldInside)
  255.                     {
  256.                         IconButtonInternalRedraw(TheButton,Inside);
  257.                         OldInside = Inside;
  258.                     }
  259.                 if (Tracking != NIL)
  260.                     {
  261.                         (*Tracking)(Refcon,Inside);
  262.                     }
  263.             } while (GetAnEvent(&X,&Y,NIL,NIL,NIL,NIL) != eMouseUp);
  264.         switch (TheButton->Mode)
  265.             {
  266.                 case eIconCheckMode:
  267.                     if (Inside)
  268.                         {
  269.                             TheButton->ButtonState = !TheButton->ButtonState;
  270.                         }
  271.                     break;
  272.                 case eIconRadioMode:
  273.                     if (Inside && !TheButton->ButtonState)
  274.                         {
  275.                             TheButton->ButtonState = !TheButton->ButtonState;
  276.                         }
  277.                      else
  278.                         {
  279.                             Inside = False;
  280.                         }
  281.                     break;
  282.                 case eIconSimpleMode:
  283.                     /* don't change button state at all, just return inside status. */
  284.                     break;
  285.                 default:
  286.                     EXECUTE(PRERR(ForceAbort,"IconButtonMouseDown:  bad mode selector"));
  287.                     break;
  288.             }
  289.         IconButtonInternalRedraw(TheButton,False);
  290.         return Inside;
  291.     }
  292.  
  293.  
  294. /* if the button is a stateful button, this forces the state to a value */
  295. void                        SetIconButtonState(IconButtonRec* TheButton, MyBoolean TheState)
  296.     {
  297.         CheckPtrExistence(TheButton);
  298.         ERROR(TheButton->Mode == eIconSimpleMode,PRERR(AllowResume,
  299.             "SetIconButtonState called on button in SimpleButton mode"));
  300.         if (TheButton->ButtonState != TheState)
  301.             {
  302.                 TheButton->ButtonState = TheState;
  303.                 RedrawIconButton(TheButton);
  304.             }
  305.     }
  306.  
  307.  
  308. /* get the value of the state variable */
  309. MyBoolean                GetIconButtonState(IconButtonRec* TheButton)
  310.     {
  311.         CheckPtrExistence(TheButton);
  312.         ERROR(TheButton->Mode == eIconSimpleMode,PRERR(AllowResume,
  313.             "GetIconButtonState called on button in SimpleButton mode"));
  314.         return TheButton->ButtonState;
  315.     }
  316.  
  317.  
  318. /* see if the specified location is within the bounds of the button */
  319. MyBoolean                IconButtonHitTest(IconButtonRec* TheButton, OrdType X, OrdType Y)
  320.     {
  321.         return (X >= TheButton->XLoc) && (Y >= TheButton->YLoc)
  322.             && (X < TheButton->XLoc + TheButton->Width)
  323.             && (Y < TheButton->YLoc + TheButton->Height);
  324.     }
  325.